use std::sync::Arc;

use winit::event_loop::{ControlFlow, EventLoop};
use winit::{
    dpi::PhysicalSize,
    event::{Event, WindowEvent},
    window::WindowBuilder,
};

use graphics::cosmic_text::Color;
use graphics::piet::{Text, TextLayoutBuilder};
use graphics::{Box2D, Graphics, Size, Size2D, Transform3D};

fn main() {
    env_logger::init();
    let event_loop = EventLoop::new().unwrap();
    let window = WindowBuilder::new()
        .with_inner_size(PhysicalSize::new(512.0, 512.0))
        .build(&event_loop)
        .unwrap();
    let window = Arc::new(window);
    // ControlFlow::Poll continuously runs the event loop, even if the OS hasn't
    // dispatched any events. This is ideal for games and similar applications.
    event_loop.set_control_flow(ControlFlow::Poll);

    // ControlFlow::Wait pauses the event loop if no events are available to process.
    // This is ideal for non-game applications that only update in response to user
    // input, and uses significantly less power/CPU time than ControlFlow::Poll.
    event_loop.set_control_flow(ControlFlow::Wait);
    let window_clone = window.clone();

    let mut graphics = pollster::block_on(Graphics::new(window_clone));
    let layout = graphics
        .font_system
        .new_text_layout("Hello World")
        .build()
        .unwrap();
    event_loop
        .run(move |event, elwt| match event {
            Event::WindowEvent {
                ref event,
                window_id,
            } if window_id == window.id() => match event {
                WindowEvent::CloseRequested => elwt.exit(),
                WindowEvent::Resized(physical_size) => {
                    graphics.resize(&Size2D::new(physical_size.width, physical_size.height));
                }
                WindowEvent::RedrawRequested => graphics.draw(|frame| {
                    frame.clear([1.0; 4]);
                    frame.set_clip(Some(Box2D::from_size(Size::splat(20.0))));
                    frame.rect(&Box2D::from_size(Size::splat(100.0)), [0.3, 0.4, 0.5, 1.0]);
                    frame.set_clip(None);
                    frame.draw_text(
                        &layout,
                        Color::rgb(10, 0, 10),
                        Transform3D::translation(10.0, 10.0, 0.0),
                    );
                }),
                _ => {}
            },
            Event::AboutToWait => {
                window.request_redraw();
            }
            _ => {}
        })
        .expect("Run loop occurs with error!");
}
